package com.dq.service.record.impl;

import com.dq.context.Constant;
import com.dq.controller.in.base.BaseAdminQuery;
import com.dq.domain.base.impl.BaseDaoImpl;
import com.dq.domain.category.Category;
import com.dq.domain.org.Org;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.goods.stock.OrgStockCheckQuery;
import com.dq.domain.record.stockcheck.StockCheckRecord;
import com.dq.mapper.stock.StockChangeRecordMapper;
import com.dq.repository.BaseRepositories;
import com.dq.service.category.CategoryService;
import com.dq.service.org.OrgService;
import com.dq.service.record.StockCheckRecordService;
import com.dq.vo.ListDataVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuhui
 * @date 2019/11/27 0027 18:03:26
 */
@Service
public class StockCheckRecordServiceImpl extends BaseRepositories implements StockCheckRecordService {

    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private StockChangeRecordMapper stockChangeRecordMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private OrgService orgService;

    @Override
    public List<StockCheckRecord> list(OrgStockCheckQuery orgStockCheckQuery) {
        Map<String, Object> query = createQuery(orgStockCheckQuery);
        return dao.find(dao.query2Hql(StockCheckRecord.class, query), query);
    }
    @Override
    public Long count(OrgStockCheckQuery orgStockCheckQuery) {
        Map<String, Object> query = createQuery(orgStockCheckQuery);
        return dao.count(dao.count2Hql(StockCheckRecord.class, query), query);
    }
    public Map<String, Object> createQuery(OrgStockCheckQuery orgStockCheckQuery) {
        SysUser loginUser = sysUserService.getUser();

        Map<String, Object> query = orgStockCheckQuery.parseMap();

        List<Long> orgidsInList = new ArrayList<>();
        if(orgStockCheckQuery.getOrgId() != null) {
            orgidsInList.add(orgStockCheckQuery.getOrgId());
        }else {
            // 只显示负责门店信息
            List<Org> orgList = orgService.getListAllByUser();
            for (Org org : orgList) {
                orgidsInList.add(org.getId());
            }
        }
        if(orgidsInList.size() > 0) {
            query.put("org_id" + BaseDaoImpl.inSqlStr, orgidsInList);
            query.remove("orgId");
        }

        if(orgStockCheckQuery.getStockCheckMainId() != null) {
            query.put("stockCheckMain_id", orgStockCheckQuery.getStockCheckMainId());
            query.remove("stockCheckMainId");
        }

        if(StringUtils.isNotBlank(orgStockCheckQuery.getGoodsName())) {
            query.put("goods_goodsName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(orgStockCheckQuery.getGoodsName()));
            query.remove("goodsName");
        }
        if(StringUtils.isNotEmpty(orgStockCheckQuery.getGoodsNo())){
            query.put("goods_goodsNo" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(orgStockCheckQuery.getGoodsNo()));
            query.remove("goodsNo");
        }
        if(StringUtils.isNotBlank(orgStockCheckQuery.getGoodsName())) {
            query.put("goods_goodsName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(orgStockCheckQuery.getGoodsName()));
            query.remove("goodsName");
        }
        if (orgStockCheckQuery.getCategoryId() != null) {
            List<Category> categoryList = categoryService.getParCategory(orgStockCheckQuery.getCategoryId());
            List<Long> idsInList = new ArrayList<>();
            idsInList.add(orgStockCheckQuery.getCategoryId());
            for (Category category : categoryList) {
                idsInList.add(category.getId());
            }
            query.put("goods_category_id" + BaseDaoImpl.inSqlStr, idsInList);
            query.remove("categoryId");
        }

        if (orgStockCheckQuery.getBeginTime() != null) {
            query.put("stockCheckMain_createTimeMain" + BaseDaoImpl.gteSqlStr, orgStockCheckQuery.getBeginTime());
            query.remove("beginTime");
        }
        if (orgStockCheckQuery.getEndTime() != null) {
            query.put("stockCheckMain_createTimeMain" + BaseDaoImpl.lteSqlStr, orgStockCheckQuery.getEndTime());
            query.remove("endTime");
        }

        query.put("createUser_id", loginUser.getId());

        return query;
    }


    /**
     * 商品库存盘点
     */
    @Override
    public void check(Integer page, Integer size, Long timeBegin, Long timeEnd) {
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT " +
                " g.id goodsId, g.goods_name goodsName," +
                " p.id productId, p.sku sku," +
                " og.count monthNum, " +
                " og.org_id orgId," +
                "" +
                " SUM(CASE WHEN change_type = 1 AND change_direction = 0 THEN ch.num ELSE 0 END) stockNum," +
                " SUM(CASE WHEN change_type = 1 AND change_direction = 1 THEN ch.num ELSE 0 END) shipmentNum" +
                " " +
                " FROM org_goods_centre og" +
                " LEFT JOIN product p ON og.product_id=p.id " +
                " LEFT JOIN goods g ON g.id= og.goods_id" +
                " LEFT JOIN stock_change_record ch ON ch.product_id = og.product_id AND ch.org_id=og.org_id" +
                " " +
                " where 1=1 ");
        if(timeBegin != null) {
            sql.append(" and ch.create_time >= ").append(timeBegin);
        }
        if(timeEnd != null) {
            sql.append(" and ch.create_time <= ").append(timeEnd);
        }

        sql.append(" GROUP BY og.product_id, og.org_id");

        // 设置动态参数
        Map<String, Object> query = new HashMap<>(16);
        if(page != null && size != null) {
            query.put("page", page);
            query.put("size", size);
        }

        System.out.println(sql.toString());

        List<Map> list = dao.findBySql2Map(sql.toString(), query);
        for (Map map : list) {
            long monthNum = 0L; long shipmentNum = 0L; long stockNum = 0L;
            if(map.get("orgId") == null || map.get("productId") == null || map.get("goodsId") == null) {
                break;
            }
            if(map.get("monthNum") != null) {
                monthNum = Long.parseLong(map.get("monthNum").toString());
            }
            if(map.get("shipmentNum") != null) {
                shipmentNum = Long.parseLong(map.get("shipmentNum").toString());
            }
            if(map.get("stockNum") != null) {
                stockNum = Long.parseLong(map.get("stockNum").toString());
            }
            insert(monthNum, Long.parseLong(map.get("goodsId").toString()),
                    Long.parseLong(map.get("orgId").toString()), shipmentNum, stockNum, Long.parseLong(map.get("productId").toString()));
        }
    }

    /**
     * 保存 实体
     */
    public void insert(Long monthNum, Long goodsId, Long orgId, Long shipmentNum, Long stockNum, Long productId) {
        // 手动开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            StringBuilder sql = new StringBuilder();
            sql.append("insert into stock_check_record" +
                    "(create_time, deleted, last_modify_time, version, month_num, goods_id, org_id, shipment_num, stock_num, product_id) " +
                    "values" +
                    "(:createTime, :deleted, :updateTime, :version, :monthNum, " +
                    ":goodsId, :orgId, :shipmentNum, :stockNum, :productId)");
            Query query = entityManager.createNativeQuery(sql.toString());
            query.setParameter("createTime", System.currentTimeMillis());
            query.setParameter("deleted", 0);
            query.setParameter("updateTime", System.currentTimeMillis());
            query.setParameter("version", Constant.VERSION_VALUE);
            query.setParameter("monthNum", monthNum);
            query.setParameter("goodsId", goodsId);
            query.setParameter("orgId", orgId);
            query.setParameter("shipmentNum", shipmentNum);
            query.setParameter("stockNum", stockNum);
            query.setParameter("productId", productId);

            query.executeUpdate();

            //  手动提交事务
            dataSourceTransactionManager.commit(transactionStatus);
        }catch (Exception e) {
            e.printStackTrace();
            // 手动回滚事务, 最好是放在catch 里面,防止程序异常而事务一直卡在哪里未提交
            dataSourceTransactionManager.rollback(transactionStatus);
        }
    }
    @Autowired
    PlatformTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;


    @Override
    public List<Map<String, Object>> selectCheck(Long orgId) {
        Map<String, Object> param = new HashMap<>(16);
        param.put("orgId", orgId);
        List<Map<String, Object>> mapList = stockChangeRecordMapper.selectCheck(param);
        for (Map<String, Object> map : mapList) {
            System.out.println(map.toString());
        }

        return mapList;
    }
}
